<?php
/**
 * Created by PhpStorm.
 * User: GZJ
 * Date: 2017/4/10
 * Time: 17:49
 */
namespace Home\Model;
use Think\Model;

class CartModel extends Model{
    protected $insertFields = 'goods_id,goods_attr_id,goods_number';
    protected $_validate = array(
        array('goods_id','require','必须选择商品',1),
        array('goods_number','ckhGoodsNumber','库存量不足','1','callback'),  //利用这个回调函数引用下面的方法去查数据库的这个商品的数量
    );
         //检查商品数量
         public function ckhGoodsNumber($goodsNumber){
             //接收商品id
             $gid = I('post.goods_id');
             //接收到的商品属性id 返回的是数组
             $gaId = I('post.goods_attr_id');
             $gaId = (string)implode(',',$gaId);//把数组转化为字符串 以逗号的形式     并且强制转成字符串形式 即使没有属性也强制转换成字符串 而不是null
             //以数字的形式升序 因为之前在做商品属性存数据的时候 定义了一个升序规则存数据库 所有这里也要
             $gaId = sort($gaId,SORT_NUMERIC);
             $gnModel = D('goods_number');
             $gn = $gnModel->field('goods_number')->where(array(
                 'goods_id'=>array('eq',$gid),
                 'goods_attr_id'=>$gaId,
             ))->find();
             if($gn['goods_number']>=$goodsNumber){
                 return true;
             }
                //如果查出来的库存量不大于或者等于接收到的数量 则不返回
         }


    /***********************重写父类的add方法**********************/

    public function add(){
        //转换成字符串
        sort($this->goods_attr_id,SORT_NUMERIC);
        $this->goods_attr_id =(string)implode(',',$this->goods_attr_id);
//        var_dump($this->goods_attr_id);exit;

        //判断session中的会员id有没有 就知道会员有没有登录了 如果有就存数据库
        $memberid = session('m_id');
        if($memberid){
            $goodsNumber = $this->goods_number;           // 先把表单中的库存量存到这个变量中,否则调用find之后就没了
            $goodsAttr = $this->goods_attr_id;
            $goods_id =  $this->goods_id;
            /***********************判断当前有没有这个商品 如果有 再点击加入购物车的时候 就要点击加入购物车的数量再加上之前数据库的数量*******************************/
            //这里是先找数据库有没有这个商品
            $has = $this->field('id')->where(array(
                'member_id'=>$memberid,
                'goods_id'=> $this->goods_id,
                'goods_number'=> $this->goods_number,
                'goods_attr_id'=> $this->goods_attr_id,
            ))->find();

            /**********这里判断*********/
            if($has)
            {
                $this->where(array(
                    'id' => array('eq', $has['id']),
                ))->setInc('goods_number', $goodsNumber);
                //这句话意思就是说如果上面查到如果有表示这个购物车的商品的id存在
                // 如果存在就针对指定的字段加几
            }else
                //如果数据库里没有 就再执行下面的添加代码 和cookie是一样的先去找cookie里有没有  有就取出来 没有就添加
                //z这里不能写this->add 这样会死循环 要调用父类的add方法去加  父类自带的add直接插入数据库的add方法
                parent::add(array(
                    'member_id'=>$memberid,
                    'goods_id'=> $goods_id,
                    'goods_number'=> $goodsNumber,
                    'goods_attr_id'=> $goodsAttr,
                ));

            return true;

        }else{
            //如果没有就存cookie
            //如果cookie里有这个数据就反序列化成数组 如果没有就返回个空
            $cart = isset($_COOKIE['cart']) ? unserialize($_COOKIE['cart']):array();
            //先拼一个下标
            $key = $this->goods_id.'-'.$this->goods_attr_id;  //把商品的id 和商品的属性id作为这个变量的下标

            if(isset($cart[$key])){       //判断再次点击加入购物车时 cookie中 如果有（当点击加入购物车同一件商品的时候）就把原来的加上点击的
                $cart[$key] += $this->goods_number;            //这就是这个下标的值再加上这个值
            }else{
                $cart[$key] = $this->goods_number;             //把商品的id 和属性id作为下表后 在把商品的数量作为值
                //最后再把这个变量存回到cookie
                /*************这里记住cookie中不能存数组 所以要序列化成字符串存进去 取的时候像上面一样 反序列花城数组即可*****************/
                setcookie('cart',serialize($cart),time()+30*86400,'/');                    //存一个月


                // （当点击加入购物车时）整个一个else方法的意思 先看cookie中有没有存这个商品的信息 如果有就返回一个数组 没有就返回一个空的
                //   如果没有 就把得到的商品id 和商品属性id 拼成字符串作为下标 把商品的数量作为值 当点击同一件商品加入购物车的时候 先检测这个商品的信息有么有
                // 有就把之前的值加上现在的 之前的商品数量就是goods_number 下标是上面拼好的 商品id和商品属性id 这样就和上面一样了
                // 如果上面都没有 就把得到的商品id 和商品属性id 拼成字符串作为下标 把商品的数量作为值 并且保存在cookie中
            }
            return TRUE;
        }
    }


    /********************************如果登录了就把存在cookie的商品信息转存到对应的数据库中***********************************/
    public function moveDatatoDb(){
        $memberid = session('m_id');
        if($memberid){
           $cart = isset($_COOKIE['cart'])?unserialize($_COOKIE['cart']):array();
            //到这里 还要判断数据库有没有这一的数据 如果有还要查出对应的会员 和对应的数据 添加到数据库里 直接把上面的代码拿来就可以用
            //如果有 可以直接foreach这个cookie【cart】这个数组  别忘了一开始存的是一维的
            foreach($cart as $k=>$v){
                //如果有 就这里循环存进来
                //cookie()的结构              $key = $this->goods_id.'-'.$this->goods_attr_id;  //把商品的id 和商品的属性id作为这个变量的下标
               //因为key值是一个字符串形式的 所以最好先转成数组 以“-”为准 分组
                $_k = explode('-',$k);
                //那么商品的id就是$_k值得第0 个下标 属性id就是$_k的第一个小标 属性id是一个字符串 可以直接存到数据库中 等到用的时候取出来再分割
                 $has = $this->field('id')->where(array(
                    'member_id'=>$memberid,
                    'goods_id'=> $_k[0],
                    'goods_number'=> $this->goods_number,
                    'goods_attr_id'=> $_k[1]
                ))->find();

                /**********这里判断 如果上面查出有这个id的 说明商品信息都是一样的 就把这个商品的数量字段再加上cookie里的数量*********/
                if($has)
                {
                    $this->where(array(
                        'id' => array('eq', $has['id']),
                    ))->setInc('goods_number', $v);
                    //这句话意思就是说如果上面查到如果有表示这个购物车的商品的id存在
                    // 如果存在就针对指定的字段加几
                    parent::add(array(
                        'member_id'=>$memberid,
                        'goods_id'=> $this-> $_k[0],
                        'goods_number'=> $this->goods_number,
                        'goods_attr_id'=> $this-> $_k[1],
                    ));

                }
                //clear cookie
                setcookie('cart','',time()-1,'/');
            }
        }
    }


    /**********************获取商品的详细信息 给显示到购物列表清单页面上***************************/
    public function cartLst(){
            $member = session('m_id');
        if($member){                          //如果有会员登录 就直接找到这个会员存在购物车（购物车表）里的商品的所有信息
            $data = $this->where(array(
                'member_id'=>array('eq',$member)
            ))->select();
        }else{
            $_data = isset($_COOKIE['cart'])? unserialize($_COOKIE['cart']):array();
            //为了方便操作 把cookie里的一维数组转换成二维数组
            //  $cart = isset($_COOKIE['cart']) ? unserialize($_COOKIE['cart']):array();
            //先拼一个下标
            //$key = $this->goods_id.'-'.$this->goods_attr_id;  //cookie的结构
            $data = array();
            foreach($_data as $k => $v){
                $_k = explode('-',$k);
                $data[] = array(
                    'goods_id'=>$_k[0],
                    'goods_attr_id'=>$_k[1],
                    'goods_number'=>$v,
                );
            }
        }
        /*********循环购物车的每件商品的详细信息*******/
        //这里因为只有商品的数量 商品的id 所以要取出商品的信息还要生成后太的商品表 用购物车表里的商品id去链表查询商品表对应id的商品信息
        $gaModel = D('Admin/goods');
        $gModel = D('goods_attr');
        foreach($data as $k=>&$v){            //加入数组的第二种方式
            $info = $gaModel->field('goods_name,logo')->find($v['goods_id']);
            //找到之后吧取到的信息 加到上面data的数组里
           // $data[$k]['goods_name']; 加入数组的第二种方式
            $v['goods_name'] = $info['goods_name'];
            $v['goods_logo'] = $info['logo'];
            //再调用商品模型里的计算价格的方法
           $v['goods_price'] = $gaModel->getMemberPrice($v['goods_id']);              //同样在把这个商品的价格放到这个二维数组里去
            /********根据当前表里的商品属性id 找到商品属性里的属性值 并且在商品属性表里找到属性表的id 链接属性表去找对对应id的属性名称***********/
            //判断 如果这个商品有商品属性的时候才进去查
            if($v['goods_attr_id']){
                $v['gData'] = $gModel->alias('a')
                    ->field('a.attr_value,b.attr_name')
                    ->join('LEFT JOIN __ATTRIBUTE__ b ON a.attr_id = b.id')
                    ->where(array(
                    'a.id'=>array('in',$v['goods_attr_id']),
                ))->select();
            }

        }
            return $data;
    }


    /*************清空购物车 删除这个会员id所有的商品*******************/
    public function clear(){
        $this->where(array(
            'member_id'=>array('eq',session('m_id')),
        ))->delete();
    }
}